import pulp
import numpy as np
import matplotlib.pyplot as plt
# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 定义食物的价格
prices = [1, 1, 1.5, 2, 0.5, 2, 4, 8, 0.5, 6, 2, 7]

# 初始化结果存储
results = []

# 定义权重范围
w1_values = np.linspace(0, 1, 50)

for w1 in w1_values:
    w2 = 1 - w1

    # 定义问题
    prob = pulp.LpProblem("Optimize_AAS_and_Price", pulp.LpMaximize)

    # 定义决策变量
    y = [[pulp.LpVariable(f"y{i}_{j}", cat='Binary') for j in range(4)] for i in range(1, 13)]
    scaled_x = [0.5*y[i-1][0] + 1.0*y[i-1][1] + 1.5*y[i-1][2] + 2.0*y[i-1][3] for i in range(1, 13)]

    # 确保每个变量只能取一个值
    for i in range(12):
        prob += pulp.lpSum(y[i]) == 1

    # 定义AAS函数
    AAS = (0.25*scaled_x[0] + 0.25*scaled_x[1] + scaled_x[2] + 0.03*scaled_x[3] + 0.02*scaled_x[5] +
           0.14*scaled_x[6] + 1.73*scaled_x[7] + 3*scaled_x[8] + 0.15*scaled_x[9] + 0.25*scaled_x[10] + 3.38*scaled_x[11])

    # 定义总价格函数
    total_price = pulp.lpSum(prices[i] * scaled_x[i] for i in range(12))

    # 定义综合目标函数
    prob += w1 * AAS - w2 * total_price, "Combined_Objective"

    # 总能量
    E = (174.5*scaled_x[0] + 174.5*scaled_x[1] + 173.4*scaled_x[2] + 77.0*scaled_x[3] + 17.96*scaled_x[4] +
         16.8*scaled_x[5] + 152.9*scaled_x[6] + 299.9*scaled_x[7] + 618.0*scaled_x[8] + 159.8*scaled_x[9] +
         178.5*scaled_x[10] + 167.0*scaled_x[11])

    # 添加约束条件
    prob += E >= 2300
    prob += E <= 2500

    # 早餐能量占比
    prob += (174.5*scaled_x[0] + 174.5*scaled_x[1] + 173.4*scaled_x[2] + 77.0*scaled_x[3] + 17.96*scaled_x[4]) >= 0.25 * E
    prob += (174.5*scaled_x[0] + 174.5*scaled_x[1] + 173.4*scaled_x[2] + 77.0*scaled_x[3] + 17.96*scaled_x[4]) <= 0.35 * E

    # 午餐能量占比
    prob += (16.8*scaled_x[5] + 152.9*scaled_x[6] + 299.9*scaled_x[7] + 618.0*scaled_x[8]) >= 0.30 * E
    prob += (16.8*scaled_x[5] + 152.9*scaled_x[6] + 299.9*scaled_x[7] + 618.0*scaled_x[8]) <= 0.40 * E

    # 晚餐能量占比
    prob += (159.8*scaled_x[9] + 178.5*scaled_x[10] + 167.0*scaled_x[11]) >= 0.30 * E
    prob += (159.8*scaled_x[9] + 178.5*scaled_x[10] + 167.0*scaled_x[11]) <= 0.40 * E

    # 总蛋白质占比
    total_protein = (5.2*scaled_x[0] + 5.2*scaled_x[1] + 9.65*scaled_x[2] + 1.8*scaled_x[3] + 0.88*scaled_x[5] +
                     1.7*scaled_x[6] + 10.85*scaled_x[7] + 13.8*scaled_x[8] + 2.41*scaled_x[9] +
                     4.01*scaled_x[10] + 19.3*scaled_x[11])
    prob += total_protein >= 0.10 * E
    prob += total_protein <= 0.15 * E

    # 总脂肪占比
    total_fat = (0.55*scaled_x[0] + 0.55*scaled_x[1] + 14.69*scaled_x[2] + 0.1*scaled_x[3] + 0.16*scaled_x[5] +
                 10.17*scaled_x[6] + 27.14*scaled_x[7] + 4.4*scaled_x[8] + 10.62*scaled_x[9] +
                 9.54*scaled_x[10] + 9.4*scaled_x[11])
    prob += total_fat >= 0.20 * E
    prob += total_fat <= 0.30 * E

    # 总碳水化合物占比
    total_carb = (37.15*scaled_x[0] + 37.15*scaled_x[1] + 0.65*scaled_x[2] + 17.3*scaled_x[3] + 2.88*scaled_x[5] +
                  13.6*scaled_x[6] + 3.0*scaled_x[7] + 130.72*scaled_x[8] + 13.62*scaled_x[9] + 20.86*scaled_x[10] + 1.3*scaled_x[11])
    prob += total_carb >= 0.50 * E
    prob += total_carb <= 0.65 * E

    # x1+x2+...+x12 >= 12
    prob += pulp.lpSum(scaled_x) >= 12 * 0.5

    # 求解问题
    prob.solve()

    # 获取解
    solution = {f"x{i}": 0.5 * y[i-1][0].varValue + 1.0 * y[i-1][1].varValue + 1.5 * y[i-1][2].varValue + 2.0 * y[i-1][3].varValue for i in range(1, 13)}

    # 替换异常值并重新计算
    for i in range(1, 13):
        if solution[f'x{i}'] <= 0 or solution[f'x{i}'] > 2:
            solution[f'x{i}'] = 1

    # 可以半份
    solution[f'x{1}'] = 1.5
    solution[f'x{4}'] = 1.5
    solution[f'x{7}'] = 1.5# 可以半份


    # 重新计算总价格和AAS
    total_price = sum(prices[i] * solution[f'x{i+1}'] for i in range(12))
    AAS = (0.25*solution['x1'] + 0.25*solution['x2'] + solution['x3'] + 0.03*solution['x4'] + 0.02*solution['x5'] +
           0.14*solution['x6'] + 1.73*solution['x7'] + 3*solution['x8'] + 0.15*solution['x9'] + 0.25*solution['x10'] + 3.38*solution['x11'])

    # 保存结果
    results.append((w1, AAS, total_price, w1 * AAS + w2 * total_price))

# 绘制图像
w1_values, AAS_values, price_values, combined_objective_values = zip(*results)

plt.figure(figsize=(12, 6), dpi=200)
plt.plot(w1_values, AAS_values, label="AAS")
plt.plot(w1_values, price_values, label="Total Price")
plt.plot(w1_values, combined_objective_values, label="Combined Objective")

plt.xlabel("w1 (AAS权重)")
plt.ylabel("价值")
plt.title("权重因素对AAS、总价和组合目标的影响-男生")
plt.legend()
plt.grid(True)
plt.savefig('综合评价-男.png', dpi=200)
plt.show()
